package com.directv.drqp.init.model;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class Attribute<T> {

	private final String name;
	private final boolean isTraversable;
	private final Method method;
	private final Field field;
	private final Class<T> parent;
	private final boolean isCollection;
	private final Class<?> type;

	/**
	 * @param parent
	 * @param name
	 * @param method
	 * @param field
	 * @param isTraversable
	 *            is this a collection. dont need to worry about maps as xsd
	 *            doesnt support that anyway
	 * @param isCollection
	 */
	public Attribute(Class<T> parent, Class<?> type, String name, Method method, Field field, boolean isTraversable, boolean isCollection) {
		super();
		this.name = name;
		this.parent = parent;

		if (method == null && field == null) {
			throw new IllegalStateException("must have either a method or a field");
		}
		this.type = type;
		this.method = method;
		this.field = field;
		this.isTraversable = isTraversable;
		this.isCollection = isCollection;
	}

	public boolean isCollection() {
		return isCollection;
	}

	public String getName() {
		return name;
	}

	public Class<?> getType() {
		return this.type;
	}

	public boolean isTraversable() {
		return isTraversable;
	}

	public Object getResult(T o) {
		if (this.method != null) {
			try {
				return method.invoke(o);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		try {
			return field.get(o);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public String toString() {
		return "Attribute [name=" + name + ", isTraversable=" + isTraversable + ", method=" + method + ", field=" + field + ", parent="
				+ parent + ", isCollection=" + isCollection + "]";
	}

}
